package com.mg.plugin.cropgrow.module;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import com.mg.model.Model;
import com.mg.model.Param;
import com.mg.model.Port;
import com.mg.plugin.cropgrow.calculator.CropGrowDateCalculator;
import com.mg.plugin.cropgrow.calculator.PlantType;
import com.mg.plugin.cropgrow.entity.CropGrowDateData;
import com.mg.plugin.cropgrow.entity.StationData;
import com.mg.pluginexample2.ModuleBase;

@SuppressWarnings("unchecked")
public class CropGrowDateModule extends ModuleBase {

    public CropGrowDateModule(int nID) {
        super(nID);
        m_alInputPort.add(new Port(this, Port.Type.Unknown));
        m_alInputPort.add(new Port(this, Port.Type.Unknown));
        m_alOutputPort.add(new Port(this, Port.Type.Unknown));
    }

    public String GetGroupName() {
        return "作物生长模型";
    }

    public String GetName() {
        return "水稻生长模型(计算作物生长时间)";
    }

    public String GetDescription() {
        return "水稻生长模型(计算作物生长时间)";
    }

    public boolean OnAttach(Port portFrom, Port portTo) {
        try {
            int i = FindPort(portFrom, false);
            if (i != -1) {
                return true;
            }
            i = FindPort(portTo, true);
            if (i == -1) {
                return false;
            }

            ArrayList<Param> alParam = new ArrayList<Param>();
            portFrom.GetModule().GetOutputParam(portFrom, alParam);

            if (alParam.size() != 1) {
                return false;
            }

            if (alParam.get(0).m_objValue != null && !(alParam.get(0).m_objValue instanceof ArrayList)) {
                m_model.OutputLog(Model.LogLevel.Info, "alParam.get(0).m_objValue != null && !(alParam.get(0).m_objValue instanceof ArrayList)");
                return false;
            }
            if (i == 0) {
                m_model.OutputLog(Model.LogLevel.Info, "SET m_inputStationDataList");
                m_inputStationDataList = (List<String>) alParam.get(0).m_objValue;
            }
            if (i == 1) {
                m_model.OutputLog(Model.LogLevel.Info, "m_inputRealityList" + alParam.get(0).m_objValue.getClass());
                m_inputRealityList = (List<String>) alParam.get(0).m_objValue;
            }

            portTo.SetType(portFrom.GetType());
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
        return true;
    }

    public boolean OnDetach(Port portFrom, Port portTo) {
        if (!super.OnDetach(portFrom, portTo))
            return false;
        try {
            int i = FindPort(portTo, true);
            if (i == -1)
                return true;
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }

    //用于 参数->XML 等
    public int GetParam(ArrayList<Param> alParam) {
        try {
            super.GetParam(alParam);
            String selectData = "A|B";
            alParam.add(new Param("PlantType", m_strPlantType, "种植类型", "计算类型A:插播、B:直播", "计算类型", Param.EditType.Select, selectData));
            alParam.add(new Param("StationNum", m_strStationNum, "站点ID", "StationNum", "参数匹配", Param.EditType.Default));
            alParam.add(new Param("StationName", m_strStationName, "站点名", "StationName", "参数匹配", Param.EditType.Default));
            alParam.add(new Param("StationCity", m_strStationCity, "站点地市", "StationCity", "参数匹配", Param.EditType.Default));
            alParam.add(new Param("Date", m_strDate, "时间", "Date", "参数匹配", Param.EditType.Default));
            alParam.add(new Param("AvgTemp", m_strAvgTemp, "平均温度", "AvgTemp", "参数匹配", Param.EditType.Default));
            alParam.add(new Param("MaxTemp", m_strMaxTemp, "最高温度", "MaxTemp", "参数匹配", Param.EditType.Default));
            alParam.add(new Param("MinTemp", m_strMinTemp, "最低温度", "MinTemp", "参数匹配", Param.EditType.Default));
            alParam.add(new Param("Sunshine", m_strSunshine, "日照时数", "Sunshine", "参数匹配", Param.EditType.Default));
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return alParam.size();
    }

    public boolean OnParamChanged(ArrayList<Param> alParam, int nIndex, Object objValue) {
        return super.OnParamChanged(alParam, nIndex, objValue);
    }

    //用于 XML->参数 等
    public int SetParam(final ArrayList<Param> alParam) {
        int i = super.SetParam(alParam);
        try {
            m_strPlantType = (String) alParam.get(i++).m_objValue;
            m_strStationNum = (String) alParam.get(i++).m_objValue;
            m_strStationName = (String) alParam.get(i++).m_objValue;
            m_strStationCity = (String) alParam.get(i++).m_objValue;
            m_strDate = (String) alParam.get(i++).m_objValue;
            m_strAvgTemp = (String) alParam.get(i++).m_objValue;
            m_strMaxTemp = (String) alParam.get(i++).m_objValue;
            m_strMinTemp = (String) alParam.get(i++).m_objValue;
            m_strSunshine = (String) alParam.get(i++).m_objValue;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return i;
    }

    public int GetOutputParam(Port port, ArrayList<Param> alParam) {
        int i = FindPort(port, false);
        if (i == -1) {
            return 0;
        }

        alParam.add(new Param("ResultString", m_listCSV));
        return alParam.size();
    }

    @SuppressWarnings("static-access")
    public boolean Execute() {
        PlantType plantType = getPlantType(m_strPlantType);
        if (m_inputRealityList != null) {
            m_inputRealityList.remove(1);
            m_inputRealityList.remove(0);
            m_inputStationDataList.addAll(m_inputRealityList);
        }

        m_listCSV.clear();
        setHeader(plantType);
        if (m_inputStationDataList != null && m_inputStationDataList.size() > 0) {
            String foreHeader = m_inputStationDataList.get(0);
            List<StationData> stationDataList = formatStationData(m_inputStationDataList, foreHeader);
            try {
                List<CropGrowDateData> cropGrowProDataList = CropGrowDateCalculator.calcCropGrowDate(stationDataList, plantType);
                for (CropGrowDateData cropGrowData : cropGrowProDataList) {
                    m_listCSV.add(cropGrowData.toString());
                }
            } catch (ParseException e) {
                e.printStackTrace();
                return false;
            }
        }

        OnParamChanged();
        return true;
    }

    //根据种植类型设置Header
    private void setHeader(PlantType plantType) {
        String head;
        String type;
        if (plantType == PlantType.B) {
            head = "id,year,stationNum,stationName,stationCity,plantDate,leaf12Date,leaf30Date,tillerDate,leaf37Date,lastLeafDate,leaf66Date,validTillerDate,highTillerDate,endTillerDate,youngEarDate,endLeafDate,earStageDate,KKL,groutPro";
            type = "String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,Double,Double";

        } else {
            head = "id,year,stationNum,stationName,stationCity,plantDate,leaf12Date,leaf30Date,leafFUDate,riceTrans,tillerDate,leaf37Date,lastLeafDate,leaf66Date,validTillerDate,highTillerDate,endTillerDate,youngEarDate,endLeafDate,earStageDate,KKL,groutPro";
            type = "String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,Double,Double";

        }
        m_listCSV.add(head);
        m_listCSV.add(type);
    }

    //获取种植类型
    private PlantType getPlantType(String strPlantType) {
        if (strPlantType.equals("A")) {
            return PlantType.A;
        }
        return PlantType.B;
    }


    private List<StationData> formatStationData(List<String> inputRealityList, String realHeader) {
        List<StationData> stationDataList = new ArrayList<StationData>();
        int realStationNumIndex = findDataIndex(realHeader, m_strStationNum);
        int realStationNameIndex = findDataIndex(realHeader, m_strStationName);
        int realStationCityIndex = findDataIndex(realHeader, m_strStationCity);
        int realDateIndex = findDataIndex(realHeader, m_strDate);
        int realAvgTempIndex = findDataIndex(realHeader, m_strAvgTemp);
        int realMaxTempIndex = findDataIndex(realHeader, m_strMaxTemp);
        int realMinTempIndex = findDataIndex(realHeader, m_strMinTemp);
        int realSunshineIndex = findDataIndex(realHeader, m_strSunshine);

        for (int i = 2; i < inputRealityList.size(); i++) {
            String[] data = inputRealityList.get(i).split(",");
            StationData stationData = new StationData();
            stationData.setStationNum(data[realStationNumIndex]);
            stationData.setStationName(data[realStationNameIndex]);
            stationData.setStationCity(data[realStationCityIndex]);
            stationData.setDate(data[realDateIndex]);
            stationData.setAvgTemp(Double.parseDouble(data[realAvgTempIndex]));
            stationData.setMaxTemp(Double.parseDouble(data[realMaxTempIndex]));
            stationData.setMinTemp(Double.parseDouble(data[realMinTempIndex]));
            stationData.setSunshine(Double.parseDouble(data[realSunshineIndex]));
            stationDataList.add(stationData);
        }
        return stationDataList;
    }


    private int findDataIndex(String realHeader, String strRain) {

        String[] data = realHeader.split(",");
        for (int i = 0; i < data.length; i++) {
            if (data[i].equalsIgnoreCase(strRain)) {
                return i;
            }
        }
        return -1;
    }

    private List<String> m_inputStationDataList = new ArrayList<String>();
    private List<String> m_inputRealityList = new ArrayList<String>();
    private List<String> m_listCSV = new ArrayList<String>();

    private String m_strPlantType;
    private String m_strStationNum;
    private String m_strStationName;
    private String m_strStationCity;
    private String m_strAvgTemp;
    private String m_strMaxTemp;
    private String m_strMinTemp;
    private String m_strSunshine;
    private String m_strDate;
}
